/**
 * @file
 * @author  Cameron Diver
 * @version 0.1
 * @brief A library to hold data. 
 * @section Description
 *
 * A container library, where all memory access and allocation
 * requests are handled invisibly, and data is copied, whereas in the
 * dynamic array library, only the pointers are stored. The size of
 * the elements is specified at initialisation, and then this is used
 * to control the data copying. For larger arrays, it may be better to
 * use a dynamic array, which does not copy the data. For obvious
 * reasons, this library can only return the pointer to a piece of
 * data, it cannot cast it, although it will provide several macros
 * which have common data types, although obviously it will not have
 * custom data types there... 
 * 
 * Another thing to note can be seen from this example: 

 * A container of size 6 is requested to have an element inserted at
 * position 12. This library will initialise enough memory to have 13
 * elements (position 12) and set position 12 to be the element. The
 * values of elements 7-11 is undefined. Also because of this, if
 * FreeContainer is called, it is likely to crash, when it tries to
 * free undefined data. You're pretty much best off using C_Append.
 */
#ifndef CONTAINER_HEADER
#define CONTAINER_HEADER

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

typedef char Byte;

typedef struct
{
	int ElementSize; /* Size of indivudual elements */
	int Size;	/* Amount of elements in the array */
	void *Array; /* The array that holds the data, set to char so
			that it handles single bytes */
}Container;

#define C_NewContainer(ElementType) (C__NewContainer(sizeof(ElementType)))

#define C_GetSize(Array) (Array->Size)

#define C_GetAsInt(Array, N) (*((int *)C_Get((Array), (N))))
#define C_GetAsString(Array, N) ((char *)C_Get((Array), (N)))
#define C_GetAsLong(Array, N) (*((long *)C_Get((Array), (N))))
/* Add more of these, try to cover all of the default (and some of the
   stdlib) types */

Container *C__NewContainer(int SizeOfElement);

void C_FreeContainer(Container *C);

int C_SetElementAt(Container *C, int N, void *Element);
void *C_Get(Container *C, int N);

int C_Append(Container *C, void *Element);
#endif /* CONTAINER_HEADER */

